package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net"
	"time"

	"fyne.io/fyne/v2"
	"github.com/go-vgo/robotgo"
)

const SOCKET_PATH = "/tmp/mouse_click_socket"

type ClickAction struct {
	Wait time.Duration
	X    int
	Y    int
}

type ActionRecord struct {
	Repead  int
	Actions []ClickAction
}

type ClickEvent struct {
	ID     int `json:"id"`
	Button int `json:"button"`
}

func play(data []byte, ex <-chan int) error {
	// data, err := ioutil.ReadFile(name)
	// if err != nil {
	// 	return fmt.Errorf("%v:'%v'", err, name)
	// }
	var records ActionRecord
	err := json.Unmarshal(data, &records)
	if err != nil {
		return err
	}
	time.Sleep(time.Second * 3)
	fyne.DoAndWait(func() {
		app1.NumLabel.SetText(T("开始执行"))
	})
LOOP1:
	for i := 0; i < records.Repead; i++ {
		for _, a := range records.Actions {
			select {
			case <-time.After(a.Wait):
				robotgo.MoveClick(a.X, a.Y)
				println("move click:", a.X, a.Y)
			case <-ex:
				println("right click break")
				break LOOP1
			}
		}
	}
	fyne.DoAndWait(func() {
		app1.NumLabel.SetText(T("执行结束"))
	})
	return nil
}

func waitRightClick(ex chan<- int, finish <-chan int) {
	conn, err := net.Dial("unix", SOCKET_PATH)
	if err != nil {
		app1.ShowError(fmt.Errorf("%v:%v", err, "Start mouse event server first."))
		ex <- 1
		close(ex)
		<-finish
		return
	} else {
		defer conn.Close()
	}

	time.Sleep(time.Second * 3)
	var buffer [64]byte
	var rd = make(chan []byte)
	defer close(rd)
	go func() {
		n, err := conn.Read(buffer[:])
		if err != nil || n < 1 {
			log.Println("read error")
			return
		}
		rd <- buffer[:n]
	}()
LOOP:
	for {
		n, err := conn.Write([]byte("get\r\n"))
		if err != nil || n < 1 {
			log.Println("write error")
			break
		}

		select {
		case buf := <-rd:
			//println(string(buf))
			var e ClickEvent
			err = json.Unmarshal(buf, &e)
			if err != nil {
				fmt.Printf("%v\n", err.Error())
				break LOOP
			} else if e.Button == 2 {
				fmt.Printf("recv button 2, finish\n")
				ex <- 1
				close(ex)
			}
		case <-finish:
			//println("finish in waitRightClick")
			break LOOP
		}
	}
	conn.Write([]byte("bye\r\n"))
}

func record(repeat int) {
	conn, err := net.Dial("unix", SOCKET_PATH)
	if err != nil {
		app1.ShowError(fmt.Errorf("%v:%v", err, "Start mouse event server first."))
		return
	}
	defer conn.Close()

	time.Sleep(time.Second * 2)

	var buffer [64]byte
	var records = make([]ClickAction, 0, 100)
	var lastTime = time.Now()
	time.Sleep(time.Second)
	println("begin record")
	for {
		n, err := conn.Write([]byte("get\r\n"))
		if err != nil || n < 1 {
			log.Println("write error")
			break
		}
		n, err = conn.Read(buffer[:])
		if err != nil || n < 1 {
			log.Println("read error")
			break
		}
		var e ClickEvent
		err = json.Unmarshal(buffer[:n], &e)
		if err != nil {
			fmt.Printf("%v\n", err.Error())
			break
		} else if e.Button == 2 {
			break
		}
		x, y := robotgo.Location()
		t := time.Now()
		records = append(records, ClickAction{Wait: t.Sub(lastTime), X: x, Y: y})
		lastTime = t
		println(string(buffer[:n]), x, y)
	}
	println("finish record")
	fyne.DoAndWait(func() {
		app1.NumLabel.SetText(T("记录结束"))
	})
	saveRecords(&ActionRecord{Repead: repeat, Actions: records})

	conn.Write([]byte("bye\r\n"))
}

func saveRecords(records *ActionRecord) {
	data, err := json.Marshal(records)
	if err != nil {
		app1.ShowError(err)
		return
	}
	app1.SaveFile(data)
}
